package com.fgxia.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fgxia.user.domain.bo.UserOrderInfoBo;
import com.fgxia.user.domain.vo.DateNodeVo;
import com.fgxia.user.domain.vo.FrightDetailVo;
import com.fgxia.user.domain.vo.UserFreightVehicleTrailVo;
import com.fgxia.user.service.IOrderInfoService;
import com.ruoyi.business.domain.FreightInfo;
import com.ruoyi.business.domain.FreightVehicleTrail;
import com.ruoyi.business.domain.OrderInfo;
import com.ruoyi.business.domain.vo.FreightVehicleTrailVo;
import com.ruoyi.business.domain.vo.OrderInfoVo;
import com.ruoyi.business.mapper.FreightInfoMapper;
import com.ruoyi.business.mapper.FreightVehicleTrailMapper;
import com.ruoyi.business.mapper.OrderInfoMapper;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.BeanCopyUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 订单信息 Service
 *
 * @author yyt
 * @date 2024-04-20
 */
@Service
@RequiredArgsConstructor
public class OrderInfoServiceImpl implements IOrderInfoService {

    private final OrderInfoMapper baseMapper;

    private final FreightVehicleTrailMapper freightVehicleTrailMapper;

    private final FreightInfoMapper freightInfoMapper;

    @Override
    public OrderInfoVo queryById(Long orderId) {
        return baseMapper.selectVoById(orderId);
    }

    @Override
    public TableDataInfo<OrderInfoVo> selectVoList(Long userId, List<String> orderStatus, PageQuery pageQuery) {
        LambdaQueryWrapper<OrderInfo> lqw = new LambdaQueryWrapper<OrderInfo>()
            .eq(OrderInfo::getRelevanceUserId, userId)
            .in(CollectionUtils.isNotEmpty(orderStatus), OrderInfo::getOrderStatus, orderStatus)
            .orderByDesc(OrderInfo::getUpdateTime);

        Page<OrderInfoVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(page);
    }

    @Override
    public Boolean insertByBo(UserOrderInfoBo bo) {
        OrderInfo orderInfo = BeanUtil.toBean(bo, OrderInfo.class);
        return baseMapper.insert(orderInfo) > 0;
    }

    @Override
    public Boolean updateByBo(UserOrderInfoBo bo) {
        OrderInfo orderInfo = BeanUtil.toBean(bo, OrderInfo.class);
        return baseMapper.updateById(orderInfo) > 0;
    }

    @Override
    public List<DateNodeVo> generateTimeSlot(int daysAhead) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startDateTime;
        if (now.toLocalTime().isAfter(LocalTime.of(17, 0))) {
            // Start from tomorrow if current time is after 18:00
            startDateTime = now.plusDays(1);
        } else {
            // Start from today if current time is before 18:00
            startDateTime = now;
        }
        LocalTime startTime = LocalTime.of(8, 0);
        LocalTime endTime = LocalTime.of(18, 0);

        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("H:mm");
        List<DateNodeVo> result = new ArrayList<>();
        for (int i = 0; i < daysAhead; i++) {
            LocalDateTime currentDate = startDateTime.plusDays(i);
            String monthValue = String.valueOf(currentDate.getMonthValue());
            String monthText = monthValue + "月";
            String dayValue = String.valueOf(currentDate.getDayOfMonth());
            String dayText = dayValue + "日";

            List<DateNodeVo> timeSlots = new ArrayList<>();
            for (LocalTime time = startTime; time.isBefore(endTime); time = time.plusHours(1)) {
                String slot = time.format(timeFormatter) + "-" + time.plusHours(1).format(timeFormatter);
                timeSlots.add(new DateNodeVo(slot, slot));
            }
            DateNodeVo dayNode = new DateNodeVo(dayText, dayValue, timeSlots);
            Optional<DateNodeVo> monthNodeOptional = result.stream().filter(node -> node.getText().equals(monthText)).findFirst();
            if (monthNodeOptional.isPresent()) {
                monthNodeOptional.get().getChildren().add(dayNode);
            } else {
                List<DateNodeVo> days = new ArrayList<>();
                days.add(dayNode);
                DateNodeVo monthNode = new DateNodeVo(monthText, monthValue, days);
                result.add(monthNode);
            }
        }

        return result;
    }

    @Override
    public List<FrightDetailVo> selectDetailById(Long userId, Long orderId) {
        // 查询订单信息
        OrderInfo orderInfo = baseMapper.selectById(orderId);

        // 查询运单信息
        LambdaQueryWrapper<FreightInfo> freightLqw = new LambdaQueryWrapper<>();
        freightLqw.eq(FreightInfo::getOrderId, orderId).orderByDesc(FreightInfo::getCreateTime);
        List<FreightInfo> freightInfos = freightInfoMapper.selectList(freightLqw);

        List<FrightDetailVo> frightDetailVos = new ArrayList<>();
        // 查询运单轨迹
        for (FreightInfo freightInfo : freightInfos) {
            FrightDetailVo frightDetailVo = new FrightDetailVo();
            frightDetailVo.setFreightId(freightInfo.getFreightId());
            frightDetailVo.setCode(freightInfo.getCode());
            frightDetailVo.setFreightStatus(freightInfo.getFreightStatus());
            frightDetailVo.setOrderNo(freightInfo.getOrderNo());
            frightDetailVo.setSendCity(orderInfo.getSendCity());
            frightDetailVo.setReceiverCity(orderInfo.getReceiverCity());
            frightDetailVo.setReceiverLatitude(orderInfo.getReceiverLatitude());
            frightDetailVo.setReceiverLongitude(orderInfo.getReceiverLongitude());
            frightDetailVo.setLoadingGoodsUrl01(freightInfo.getLoadingGoodsUrl01());
            frightDetailVo.setLoadingGoodsUrl02(freightInfo.getLoadingGoodsUrl02());
            frightDetailVo.setLoadingGoodsUrl03(freightInfo.getLoadingGoodsUrl03());
            frightDetailVo.setReceivingGoodsUrl01(freightInfo.getReceivingGoodsUrl01());
            frightDetailVo.setReceivingGoodsUrl02(freightInfo.getReceivingGoodsUrl02());
            frightDetailVo.setReceivingGoodsUrl03(freightInfo.getReceivingGoodsUrl03());

            LambdaQueryWrapper<FreightVehicleTrail> trailLqw = new LambdaQueryWrapper<>();
            trailLqw.eq(FreightVehicleTrail::getFreightId, freightInfo.getFreightId())
                .orderByDesc(FreightVehicleTrail::getRecordTime);

            List<FreightVehicleTrail> freightVehicleTrails = freightVehicleTrailMapper.selectList(trailLqw);
            frightDetailVo.setFreightVehicleTrailVos(BeanCopyUtils.copyList(freightVehicleTrails, UserFreightVehicleTrailVo.class));

            frightDetailVos.add(frightDetailVo);
        }

        return frightDetailVos;
    }
}
